网站导航:首页开源项目 USB开源项目:Easy USB 51 Programer  

目录导航

   
  1、项目简介
USB开发基础
1、USB接口的优点及开发难易度
2、USB设备的开发流程
3、USB接口芯片(USB控制器)的选择
4、了解USB的通讯过程
5、USB命令(请求)和USB描述符
6、实例讲解USB的枚举(配置)过程
准备工作
1、需要哪些工具
2、电路原理图
3、手工制作您的电路板
4、测试您的硬件
HID设备类
1、让PC机找到我们的硬件
2、如何成为一个HID设备(模拟鼠标)
3、如何成为一个HID设备(模拟键盘)
4、如何与HID设备通讯(一)
5、如何与HID设备通讯(二)
6、51编程器的实现
Windows USB 驱动程序(自定义设备)
1、Windows驱动开发基础
2、开发环境配置
3、第一个实例-Hello Wdm(一)
4、第一个实例-Hello Wdm(二)
5、真正的实例—驱动我们的实验板
6、真正的实例—测试驱动程序
7、真正的实例—控制LED及读取按键状态
8、如何编写应用程序
   

相关产品    淘宝网店
     
 

 
  更多...  
 
 
真正的实例—控制LED及读取按键状态 查看/参与此开源项目相关讨论
 

1、完善下位机程序

  1)修改Chap_9.c文件中的control_handler函数,内容如下:

 
  1. /*************************************************************  
  2. ** 函数名称: void control_handler(void)  
  3. ** 功能描述: 控制传输  
  4. **************************************************************/  
  5. void control_handler(void)   
  6. {   
  7.     INT8U type, req;   
  8.     INT16U  wValue;   
  9.        
  10.   
  11.     type = ControlData.DeviceRequest.bmRequestType & USB_REQUEST_TYPE_MASK;    
  12.                                                 //读取请求代码   
  13.     req = ControlData.DeviceRequest.bRequest & USB_REQUEST_MASK;   
  14.        
  15.     wValue = ControlData.DeviceRequest.wValue;   
  16.        
  17.     if (type == USB_STANDARD_REQUEST)   
  18.         (*StandardDeviceRequest[req])();        //标准请求处理   
  19.     else if (type == USB_VENDOR_REQUEST)        //厂商请求   
  20.         (*VendorDeviceRequest[req])(wValue);   
  21.     //else if(type == USB_CLASS_REQUEST)   
  22.     //  (*ClassDeviceRequest[req])();           //类请求,如大容量类   
  23.     else  
  24.         stall_ep0();                            //无效请求,返回STALL                 
  25. }   

  2)在Chap_9.c文件中增加以下函数:

 
  1. sbit K1 = P3^5;   
  2. sbit K2 = P3^6;   
  3.   
  4. /****************************************  
  5. ** 函数名称: void control_led(INT16U wValue)  
  6. ** 功能描述: 控制扩展板EXT-BOARD-A上的LED  
  7. ** 参    数:INT16U wValue->控制值,低字节有效,如wValue为0x0000时LED全灭,wValue为0x00FF时LED全亮  
  8. *****************************************/  
  9. void control_led(INT16U wValue)   
  10. {   
  11.     P0 =    wValue % 256;       //返回一个空的数据表示执行完毕   
  12.        
  13.     single_transmit(0, 0);      //返回一个空的数据表示执行完毕   
  14. }   
  15.   
  16. /****************************************  
  17. ** 函数名称: void get_key_state(INT16U wValue)  
  18. ** 功能描述: 取得扩展板EXT-BOARD-A上按键状态  
  19. ** 参    数:INT16U wValue->无意义  
  20. *****************************************/  
  21. void get_key_state(INT16U wValue)   
  22. {   
  23.     INT8U ucKeyState[1],i;     
  24.        
  25.     ucKeyState[0]   = 0x00;    
  26.     K1  = 1;   
  27.     K2  = 1;   
  28.     for(i=0;i<100;i++);   
  29.        
  30.     if(~K1) //K1按下   
  31.     {   
  32.         ucKeyState[0]   |= 0x01;   
  33.     }   
  34.        
  35.     if(~K2) //K2按下   
  36.     {   
  37.         ucKeyState[0]   |= 0x02;   
  38.     }   
  39.            
  40.     single_transmit(ucKeyState,1);   
  41. }   
  42.   
  43. //USB厂商请求入口地址指针表   
  44. code void (*VendorDeviceRequest[]) (INT16U wValue) =   
  45. {   
  46.     control_led,   
  47.     get_key_state      
  48. };   

  3)向Chap_9.h中增加以下内容

 
  1. extern code void (*VendorDeviceRequest[])(INT16U wValue);   
  2. extern void control_led(INT16U wValue);   
  3. extern void get_key_state(INT16U wValue);   

下载修改好后的源代码

2、修改Windows驱动程序

  1)完善IOCTL_LED_Handler函数,内容如下

 
  1. ////////////////////////////////////////////////////////////////////////   
  2. //  Easy_USB_51_ProgramerDevice::IOCTL_LED_Handler   
  3. //   
  4. //  Routine Description:   
  5. //      Handler for IO Control Code IOCTL_LED   
  6. //   
  7. //  Parameters:   
  8. //      I - IRP containing IOCTL request   
  9. //   
  10. //  Return Value:   
  11. //      NTSTATUS - Status code indicating success or failure   
  12. //   
  13. //  Comments:   
  14. //      This routine implements the IOCTL_LED function.   
  15. //      This routine runs at passive level.   
  16. //   
  17.   
  18. NTSTATUS Easy_USB_51_ProgramerDevice::IOCTL_LED_Handler(KIrp I)   
  19. {   
  20.     NTSTATUS status = STATUS_SUCCESS;   
  21.   
  22.     t << "Entering Easy_USB_51_ProgramerDevice::IOCTL_LED_Handler, " << I << EOL;   
  23.     // TODO:    Verify that the input parameters are correct   
  24.     //          If not, return STATUS_INVALID_PARAMETER   
  25.     //检查输入参数是否正确,如果不正确,返回 STATUS_INVALID_PARAMETER    
  26.     if(I.IoctlOutputBufferSize() || !I.IoctlBuffer())    
  27.     {   
  28.         status  = STATUS_INVALID_PARAMETER;   
  29.         return status;    
  30.     }   
  31.        
  32.     // TODO:    Handle the the IOCTL_LED request, or    
  33.     //          defer the processing of the IRP (i.e. by queuing) and set   
  34.     //          status to STATUS_PENDING.   
  35.     //处理 IOCTL_LED请求    
  36.     PURB pUrb = m_Lower.BuildVendorRequest(NULL, // 传输缓冲区    
  37.         0, //  传输缓冲区大小    
  38.         0, //  请求保留位    
  39.         CMD_CTL_LED, //厂商请求代码值,定义:#define CMD_CTL_LED 0x00   
  40.         (UCHAR)(*(PUCHAR)I.IoctlBuffer()),  //控制LED的值,为0x00时代表全灭,为0xFF时代表全亮   
  41.         FALSE,       // bIn    
  42.         TRUE,       // bShortOk    
  43.         NULL,       // Link    
  44.         0        // Index    
  45.         );    
  46.   
  47.     if(pUrb)   
  48.     {   
  49.         //向下传送URB    
  50.         status = m_Lower.SubmitUrb(pUrb, NULL, NULL, 1000L);   
  51.     }   
  52.     else  
  53.     {   
  54.         status  = STATUS_PENDING;   
  55.     }   
  56.   
  57.     delete pUrb;   
  58. // TODO:    Assuming that the request was handled here. Set I.Information   
  59. //          to indicate how much data to copy back to the user.   
  60.     if(NT_SUCCESS(status))     
  61.     {    
  62.         I.Information() = pUrb->UrbControlVendorClassRequest.TransferBufferLength;    
  63.     }    
  64.     else  
  65.     {   
  66.         I.Information() = 0;   
  67.     }   
  68.        
  69.     I.Status()      = status;   
  70.   
  71.     return status;   
  72. }   

  2)完善IOCTL_GET_KEY_Handler函数,内容如下

 
  1. ////////////////////////////////////////////////////////////////////////   
  2. //  Easy_USB_51_ProgramerDevice::IOCTL_GET_KEY_Handler   
  3. //   
  4. //  Routine Description:   
  5. //      Handler for IO Control Code IOCTL_GET_KEY   
  6. //   
  7. //  Parameters:   
  8. //      I - IRP containing IOCTL request   
  9. //   
  10. //  Return Value:   
  11. //      NTSTATUS - Status code indicating success or failure   
  12. //   
  13. //  Comments:   
  14. //      This routine implements the IOCTL_GET_KEY function.   
  15. //      This routine runs at passive level.   
  16. //   
  17.   
  18. NTSTATUS Easy_USB_51_ProgramerDevice::IOCTL_GET_KEY_Handler(KIrp I)   
  19. {   
  20.     NTSTATUS status = STATUS_SUCCESS;   
  21.   
  22.     t << "Entering Easy_USB_51_ProgramerDevice::IOCTL_GET_KEY_Handler, " << I << EOL;   
  23. // TODO:    Verify that the input parameters are correct   
  24. //          If not, return STATUS_INVALID_PARAMETER   
  25.   
  26. // TODO:    Handle the the IOCTL_GET_KEY request, or    
  27. //          defer the processing of the IRP (i.e. by queuing) and set   
  28. //          status to STATUS_PENDING.   
  29.         //处理 IOCTL_LED请求    
  30.     PURB pUrb = m_Lower.BuildVendorRequest((PUCHAR)I.IoctlBuffer(), // 传输缓冲区    
  31.         1, //  传输缓冲区大小    
  32.         0, //  请求保留位    
  33.         CMD_GET_KEY_STATUS, //厂商请求代码值,定义:#define CMD_GET_KEY_STATUS 0x01   
  34.         0,   
  35.         TRUE,       // bIn    
  36.         TRUE,       // bShortOk    
  37.         NULL,       // Link    
  38.         0        // Index    
  39.         );    
  40.   
  41.     if(pUrb)   
  42.     {   
  43.         //向下传送URB    
  44.         status = m_Lower.SubmitUrb(pUrb, NULL, NULL, 1000L);   
  45.     }   
  46.     else  
  47.     {   
  48.         status  = STATUS_PENDING;   
  49.     }   
  50.   
  51.     delete pUrb;   
  52.   
  53. // TODO:    Assuming that the request was handled here. Set I.Information   
  54. //          to indicate how much data to copy back to the user.   
  55.     if(NT_SUCCESS(status))     
  56.     {    
  57.         I.Information() = pUrb->UrbControlVendorClassRequest.TransferBufferLength;    
  58.     }    
  59.     else  
  60.     {   
  61.         I.Information() = 0;   
  62.     }   
  63.        
  64.     I.Status()      = status;   
  65.   
  66.     return status;   
  67. }   

  3)在Easy_USB_51_ProgramerDevice.h中加入如下宏定义:

 
  1. #define CMD_CTL_LED 0x00   
  2. #define CMD_GET_KEY_STATUS 0x01   

3、修改测试程序

  1)完善Test_IOCTL_LED函数,内容如下:

 
  1. ////////////////////////////////////////////////////////////////////////   
  2. // Test_IOCTL_LED   
  3. //   
  4. //      Test one Io Control Code   
  5. //   
  6. // TODO:   
  7. //      Pass appropriate arguments to your device and check   
  8. //      the return value   
  9. //   
  10. void Test_IOCTL_LED(void)   
  11. {   
  12. // Note that Input and Output are named from the point of view   
  13. // of the DEVICE:   
  14. //      bufInput  supplies data to the device   
  15. //      bufOutput is written by the device to return data to this application   
  16.   
  17.     CHAR    bufInput[IOCTL_INBUF_SIZE];     // Input to device   
  18.     CHAR    bufOutput[IOCTL_OUTBUF_SIZE];   // Output from device   
  19.     ULONG   nOutput;                        // Count written to bufOutput   
  20.   
  21.     bufInput[0] = 0x03;   
  22.   
  23.     // Call device IO Control interface (IOCTL_LED) in driver   
  24.     printf("Issuing Ioctl to device - ");   
  25.     if (!DeviceIoControl(hDevice,   
  26.                          IOCTL_LED,   
  27.                          bufInput,   
  28.                          IOCTL_INBUF_SIZE,   
  29.                          NULL,   
  30.                          0,   
  31.                          NULL,   
  32.                          NULL)   
  33.        )   
  34.     {   
  35.         printf("ERROR: DeviceIoControl returns %0x.", GetLastError());   
  36.         Exit(1);   
  37.     }   
  38. }   

  2)完善Test_IOCTL_GET_KEY函数,内容如下

 
  1. ////////////////////////////////////////////////////////////////////////   
  2. // Test_IOCTL_GET_KEY   
  3. //   
  4. //      Test one Io Control Code   
  5. //   
  6. // TODO:   
  7. //      Pass appropriate arguments to your device and check   
  8. //      the return value   
  9. //   
  10. void Test_IOCTL_GET_KEY(void)   
  11. {   
  12. // Note that Input and Output are named from the point of view   
  13. // of the DEVICE:   
  14. //      bufInput  supplies data to the device   
  15. //      bufOutput is written by the device to return data to this application   
  16.   
  17.     CHAR    bufInput[IOCTL_INBUF_SIZE];     // Input to device   
  18.     CHAR    bufOutput[IOCTL_OUTBUF_SIZE];   // Output from device   
  19.     ULONG   nOutput;                        // Count written to bufOutput   
  20.   
  21.   
  22.     // Call device IO Control interface (IOCTL_GET_KEY) in driver   
  23.     printf("Issuing Ioctl to device - ");   
  24.     if (!DeviceIoControl(hDevice,   
  25.                          IOCTL_GET_KEY,   
  26.                          NULL,   
  27.                          0,   
  28.                          bufOutput,   
  29.                          IOCTL_OUTBUF_SIZE,   
  30.                          &nOutput,   
  31.                          NULL)   
  32.        )   
  33.     {   
  34.         printf("ERROR: DeviceIoControl returns %0x.\n", GetLastError());   
  35.         Exit(1);   
  36.     }   
  37.     else if(nOutput == 0)   
  38.     {   
  39.         printf("ERROR: DeviceIoControl complete, but Device not respond");   
  40.     }   
  41.     else  
  42.     {   
  43.         printf("Device responsed data:0x%.2x\n",bufOutput[0]);   
  44.   
  45.         if(bufOutput[0] & 0x01) //K1 Pressed   
  46.         {   
  47.             printf("K1 Pressed\n");   
  48.         }   
  49.         else  
  50.         {   
  51.             printf("K1 Unpressed\n");   
  52.         }   
  53.   
  54.         if(bufOutput[0] & 0x02) //K1 Pressed   
  55.         {   
  56.             printf("K2 Pressed\n");   
  57.         }   
  58.         else  
  59.         {   
  60.             printf("K2 Unpressed\n");   
  61.         }   
  62.     }   
  63. }   

  3)编译驱动程序和测试程序,重新安装驱动程序

下载编译好的驱动

下载编译好后的测试程序

下载驱动和测试程序源代码(需要放到C:\Easy_USB_51_Programer目录)

  4)在命令行窗口中运行测试程序,键入:TestApp i 0,代表发送请求代码为0x00的厂商请求,这个请求是控制LED的,运行结果如下:

  运行testapp i 0 后发现扩展板上的D0和D1被点亮了

 

(呵呵,我已经投PCB了,所以没有用手工制作的那个原始东东来展示)

  这是用Bus Hound抓到的数据

  5)在命令行窗口中运行测试程序,键入:TestApp i 1,代表发送请求代码为0x01的厂商请求,这个请求是读取扩展板EXT-BOARD-A上按键状的,运行结果如下:

  下图是用BusHound抓到的数据

 
 
 
本站程序由百合电子工作室开发和维护
Copyright @ baihe electric studio
渝ICP备09006681号-4